package utils;

import com.google.common.reflect.TypeToken;
import com.google.gson.*;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Type;
import java.text.DateFormat;
import java.util.*;

/**
 * @author: Lishuai
 * @date: 2018/8/19 16:34
 * @description
 */
public class Json2MapUtil {
	private static Type type = new TypeToken<TreeMap<String, Object>>() {
		private static final long serialVersionUID = 1L;
	}.getType();

	private static Gson gson = new GsonBuilder().setDateFormat(DateFormat.LONG)
			.registerTypeAdapter(type, new JsonDeserializer<TreeMap<String, Object>>() {
				@Override
				public TreeMap<String, Object> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
					TreeMap<String, Object> treeMap = new TreeMap<String, Object>();
					JsonObject jsonObject = json.getAsJsonObject();
					Set<Map.Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
					for (Map.Entry<String, JsonElement> entry : entrySet) {
						String key = entry.getKey();
						JsonElement value = entry.getValue();
						if (value == null) {
							treeMap.put(key, null);
							continue;
						}

						if (value.isJsonObject()) {
							treeMap.put(key, this.deserialize(value, typeOfT, context));
						} else if (value.isJsonArray()) {
							JsonArray array = value.getAsJsonArray();
							List<TreeMap<String, Object>> list = new ArrayList<TreeMap<String, Object>>();
							for (int i = 0; i < array.size(); i++) {
								JsonObject object = array.get(i).getAsJsonObject();
								list.add(this.deserialize(object, typeOfT, context));
							}
							treeMap.put(key, list);
						} else {
							if (StringUtils.endsWith(key, "_count") || StringUtils.endsWith(key, "_number")) {
								treeMap.put(key, value.getAsLong());
							} else if (StringUtils.startsWith(key, "is_") || StringUtils.endsWith(key, "_offset")) {
								treeMap.put(key, value.getAsInt());
							} else if (StringUtils.endsWith(key, "time")) {
								treeMap.put(key, value.getAsLong());
							} else {
								treeMap.put(key, value.getAsString());
							}
						}
					}
					return treeMap;
				}
			}).create();
	
	
	public static Map<String, Object> convert(String json){
		return gson.fromJson(json, type);
	}
	public static String toJson(Object o){
		return gson.toJson(o);
	}
}
